﻿using UnityEngine;

/// <summary>
/// 燃烧元素
/// </summary>
public class BurningAura : IElementAura
{
    private const float Interval = 0.25f;
    private const float GrassGaugeLossSpeed = 0.4f;
    private const float Radius = 1f; // 燃烧半径

    private readonly IElementHolder _holder;
    private readonly IElementAura _grassAura;
    private readonly IElementAura _quickAura;
    private float _intervalTimer;
    private float _gauge;

    private readonly Collider[] _cache = new Collider[99]; // 如果燃烧范围内有更多的碰撞器，修改这个数组大小

    public GameObject Source { get; set; }

    /// <summary>
    /// 元素量
    /// </summary>
    public float Gauge
    {
        get => _gauge;
        set
        {
            if (value <= 0f)
            {
                _gauge = 0f;
                _grassAura.IsGaugeLoss = true;
            }
            else
            {
                _gauge = value;
            }
        }
    }

    public ElementType ElementType => ElementType.Fire;

    public bool IsGaugeLoss { get; set; } = false;

    public BurningAura(IElementHolder holder)
    {
        _holder = holder;
        _grassAura = _holder.GetElementAura("草");
        _quickAura = _holder.GetElementAura("激化");
    }

    public void Attach(float gauge, GameObject source)
    {
        Gauge = gauge;
        Source = source;
        _intervalTimer = Interval;
        _grassAura.IsGaugeLoss = false;
        _quickAura.IsGaugeLoss = false;
    }

    public void Update(float deltaTime)
    {
        if (Gauge > 0f)
        {
            _intervalTimer += deltaTime;
            if (_intervalTimer >= Interval)
            {
                TakeDamage();
                _intervalTimer -= Interval;
            }

            _grassAura.Gauge -= GrassGaugeLossSpeed * deltaTime;
            _quickAura.Gauge -= GrassGaugeLossSpeed * deltaTime;
            if (_grassAura.Gauge <= 0f && _quickAura.Gauge <= 0f)
            {
                Gauge = 0f;
            }
        }
    }

    private void TakeDamage()
    {
        // 造成范围火伤害，半径1米，触发1单位火
        var count = Physics.OverlapSphereNonAlloc(_holder.Owner.transform.position, Radius,
            _cache);
        for (int i = 0; i < count; i++)
        {
            if (_cache[i].TryGetComponent(out ActorDamageable damageable))
            {
                var attackData = new AttackData
                {
                    Damage = 10f,
                    Source = Source,
                    ElementType = ElementType.Fire,
                    ElementGauge = 1f,
                    StrikeType = StrikeType.None
                };
                damageable.TakeDamage(attackData);
            }
        }
    }
}